package com.easygroup.ngarihealth.plugin

import com.android.build.api.transform.*
import com.android.build.gradle.api.BaseVariant
import com.easygroup.ngarihealth.easymodule.ModuleCollection
import com.google.common.collect.ImmutableSet
import javassist.ClassPool
import org.apache.commons.io.FileUtils
import org.gradle.api.DomainObjectSet
import org.gradle.api.Project

/**
 * Created by fuxiaohua on 2021/5/10 0010.
 */
class EasyModuleTransform extends Transform {

    private static final String TRANSFORM_NAME = 'EasyModule'
    private Set<String> packageNames = new TreeSet<>()
    private Project project
    private ClassPool classPool

    EasyModuleTransform(Project project, DomainObjectSet<BaseVariant> variants) {
        this.project = project
        variants.each { variant ->
            packageNames.add(variant.applicationId)
            log("variants id = " + variant.applicationId)
        }
        project.afterEvaluate {
            if (project.configurations.findByName("easymodule") != null) {
                String[] packages = project.esaymodule.packageNames
                if (packages != null && packages.length > 0) {
                    packages.each { packageName ->
                        packageNames.add(packageName)
                    }
                }
            }
            packageNames.add(ModuleCollection.class.package.name)
        }
    }

    @Override
    String getName() {
        return TRANSFORM_NAME
    }

    @Override
    Set<QualifiedContent.ContentType> getInputTypes() {
        return ImmutableSet.of(QualifiedContent.DefaultContentType.CLASSES)
    }

    @Override
    Set<QualifiedContent.Scope> getScopes() {
        return ImmutableSet.of(
                QualifiedContent.Scope.PROJECT,
                QualifiedContent.Scope.SUB_PROJECTS,
                QualifiedContent.Scope.EXTERNAL_LIBRARIES
        )
    }

    @Override
    boolean isIncremental() {
        return true
    }

    @Override
    void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {
        final def start = System.currentTimeMillis()
        log("Transform Task start, incremental ${transformInvocation.incremental}.")
        // 文件输出提供者
        def outputProvider = transformInvocation.outputProvider
        classPool = new ClassPool(true)
        // 类池导包
        packageNames.each {
            log("导入----->$it")
            classPool.importPackage(it)
        }
        Inject inject = new Inject(project, classPool)
        // 扫描所有的文件 transform之前的产物
        transformInvocation.inputs.each {
            // td--扫描class文件夹
            it.directoryInputs.parallelStream().each {
                def dst = outputProvider.getContentLocation(it.name, it.contentTypes, it.scopes, Format.DIRECTORY)
                // log("directoryInputs ------>$it.file")
                // log("directoryInputs dst-->$dst")
                // 将app模块的生成的class文件复制到transform目录下
                FileUtils.copyDirectory(it.file, dst)
                // 收集类文件
                inject.collectClassFile(dst)
            }
            // td--扫描jar文件
            it.jarInputs.parallelStream().each {
                def dst = outputProvider.getContentLocation(Utils.getJarHexName(it, true), it.contentTypes, it.scopes, Format.JAR)
                // log("jarInputs---->$it.file")
                // log("jarInputs dst-->$it")
                // 将项目用到的各种jar复制到transform目录下, 包括lib类型的模块(jar)
                FileUtils.copyFile(it.file, dst)
                // 收集类文件
                inject.collectClassJarFile(dst)
            }
        }
        final def preEnd = System.currentTimeMillis()
        def preTime = (preEnd - start) / 1000
        log("Transform Task files copied with ${preTime}s.")
        // td--处理
        inject.process()
        classPool.clearImportedPackages()
        final def end = System.currentTimeMillis()
        def time = (end - start) / 1000
        log("Transform Task finished with ${time}s.")
    }

    private void log(String msg, Object... args) {
        def text = String.format(msg, args)
        project.getLogger().error("[ModuleTransform]:${text}")
    }
}




